一種包裝程式,可以重複使用,會輸入的值執行某些處理程序後,再將結果回傳機制
function 函數名稱(參數列表) {
// 函數體
return 回傳值;
}
function sum(a, b) {
return a + b;
}
var result = sum(2, 3);
console.log(result); // 5
用 return
來回傳值和函數
function createAdder(a) {
return function(b) {
return a + b;
};
}
var adder = createAdder(2);
console.log(adder(3)); // 5
直接在程式碼定義函數
和物件函數(object function)
最大區別
原始函數沒有自己原型鏈,無法透過prototype
屬性存取或繼承物件屬性和方法
function myFunction() {
// 函數體
}
function add(x, y) {
return x + y;
}
console.log(add(2, 3)); // 5
可以像物件函數使用,透過 call()
、apply()
傳遞參數和設定作用域
function foo(x) {
console.log(x);
}
foo.call(null, "bar"); // bar
foo.apply(null, ["bar"]); // bar
可以透過 bind()
綁定到特定物件
function foo() {
console.log(this.name);
}
var bar = {
name: "bar"
};
var boundFoo = foo.bind(bar);
boundFoo(); // bar
原始函數不可變的,無法修改原始定義
如果要修改原始函數行為
可以使用 Function.prototype.bind()
Function.prototype.defineProperty()
function foo(x) {
console.log(x);
}
var boundFoo = foo.bind(null, 20);
boundFoo(); // 20
function foo(x) {
console.log(x);
}
Object.defineProperty(foo, "name", {
value: "bar"
});
foo(); // bar
新函數表達式,在ES6語法比傳統函數更簡潔、更易讀,適當情況下使用箭頭函數可以提高程式的可讀性和可維護性,具有一些特殊行為
// 簡寫體
const foo = (x) => x * 2;
// 塊體
const bar = (x) => {
return x * 2;
};
箭頭函數簡寫體只有一個運算式,會自動返回運算式結果
塊體可以包含多個語句,需要使用 return
語句來返回結果
this
關鍵字,因此 this
在箭頭函數始終指向函數定義位置arguments
物件,因此無法直接存取函數所有參數// 匿名函數
const add = (x, y) => x + y;
console.log(add(1, 2)); // 3
// 回呼函數
const button = document.querySelector("button");
button.addEventListener("click", () => {
console.log("clicked");
});
// 方法
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
return () => console.log("Hello " + this.name);
}
}
const person = new Person("Cindy");
const hello = person.sayHello();
hello(); // Hello Cindy
指沒有名稱的函數
// 簡寫體
const foo = (x, y) => x + y;
// 塊體
const bar = (x, y) => {
return x + y;
};
匿名函數簡寫體只有一個運算式,會自動返回運算式結果
塊體可以包含多個語句,需要使用 return
語句返回結果
使用匿名函數處理
click
事件
按鈕被點擊時,匿名函數會被調用,在控制台輸出clicked
匿名函數也可以用來實現方法
const button = document.querySelector("button");
button.addEventListener("click", () => {
console.log("clicked");
});
使用匿名函數來實現
Person
物件的sayHello()
sayHello()
返回一個匿名函數,在控制台輸出Hello Cindy Huang
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
return () => console.log("Hello " + this.name);
}
}
const person = new Person("Cindy Huang");
const hello = person.sayHello();
hello(); // Hello Cindy Huang
匿名函數可以用來實現閉包
makeAdder()
返回一個匿名函數,訪問x變量的值
在add5變數,將x變量的值設置為7
因此add5()
函數會返回 7 和 y 變量的和 //27
const makeAdder = (x) => (y) => x + y;
const add5 = makeAdder(5);
console.log(add5(20)); // 27
需要 根據具體情況
選擇是否使用 匿名函數
需要 簡潔
和靈活性
,可以使用 匿名函數
需要 可讀性
和可維護性
,可以使用 傳統函數
一種函數被宣告時在
作用域環境(lexical environment)
的組合
function foo() {
// 作用域環境
const x = 20;
return (y) => x + y;
}
// 閉包
const bar = foo();
// 調用閉包
console.log(bar(10)); // 30
function foo() {
// 私有變量
const x = 10;
return () => x;
}
const bar = foo();
console.log(bar()); // 10
// 嘗試外部訪問 x 變量
console.log(x); // x is not defined
function foo(callback) {
// 回調函數
callback();
}
foo(() => console.log("Hello world")); // Hello world
function foo() {
// 延遲求值
return new Promise((resolve) => {
const x = Math.random();
setTimeout(() => resolve(x), 1000);
});
}
const bar = foo();
console.log(bar); // Promise {<pending>}
// 獲取結果
bar.then((x) => console.log(x)); // 隨機數
資料來源:JavaScript Function (函數)
Function 函式
閉包,原來這就是閉包啊!